package com.lihonghao.server;

import cn.hutool.core.thread.ThreadUtil;
import cn.hutool.extra.spring.SpringUtil;
import com.lihonghao.handle.HttpForwardHandler;
import io.netty.bootstrap.ServerBootstrap;
import io.netty.channel.*;
import io.netty.channel.nio.NioEventLoopGroup;
import io.netty.channel.socket.SocketChannel;
import io.netty.channel.socket.nio.NioServerSocketChannel;
import io.netty.handler.codec.http.HttpObjectAggregator;
import io.netty.handler.codec.http.HttpServerCodec;
import io.netty.handler.codec.string.StringDecoder;
import io.netty.handler.codec.string.StringEncoder;
import io.netty.handler.logging.LogLevel;
import io.netty.handler.logging.LoggingHandler;
import org.springframework.boot.ApplicationArguments;
import org.springframework.boot.ApplicationRunner;
import org.springframework.stereotype.Component;

import java.net.InetSocketAddress;
@Component
public class InterLinkService implements ApplicationRunner {
    @Override
    public void run(ApplicationArguments args) throws Exception {
        InterLinkService interLinkService = new InterLinkService();
        interLinkService.start();
    }

    int port = 9527;

    public InterLinkService() {
    }

    public InterLinkService(int port) {
        this.port = port;
    }

    public void start() throws InterruptedException {
        ServerBootstrap bootstrap = new ServerBootstrap();
        EventLoopGroup boss = new NioEventLoopGroup();
        EventLoopGroup work = new NioEventLoopGroup();
        bootstrap.group(boss, work)
                .handler(new LoggingHandler(LogLevel.DEBUG))
                .channel(NioServerSocketChannel.class)
                .childHandler(new InterLinkInitializer());
        bootstrap.childOption(ChannelOption.SO_KEEPALIVE, true);// 启用 TCP Keep-Alive
        ChannelFuture f = bootstrap.bind(new InetSocketAddress(port)).sync();
        System.out.println("Server started on port " + port);
        ThreadUtil.execute(() -> {
            try {
                f.channel().closeFuture().sync();
            } catch (InterruptedException e) {
                throw new RuntimeException(e);
            }
        });
    }

    class InterLinkInitializer extends ChannelInitializer<SocketChannel> {

        @Override
        protected void initChannel(SocketChannel channel) throws Exception {
            ChannelPipeline pipeline = channel.pipeline();
            pipeline.addLast(new LoggingHandler(LogLevel.DEBUG));
            pipeline.addLast(new StringDecoder());
            pipeline.addLast(SpringUtil.getBean(HttpForwardHandler.class));// 请求处理器
            pipeline.addLast(new StringEncoder());

        }

    }

}
